package gui;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.AttributedString;
import java.text.BreakIterator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

import javax.swing.*;
import javax.swing.border.Border;

import Projektarbete.ContactTabListFiller;
import Projektarbete.User;

import staticClasses.F;
import staticClasses.IP;
import staticClasses.Port;

/**
 * 
 * @author August, Victor
 */
public class ChatWindow extends javax.swing.JPanel implements KeyListener {

	/**
	 * Creates new form ChatWindow Whole class remade by August 26-04-12! Latest
	 * version!
	 */

	ContactTabListFiller filler;
	private Socket connectSocket;
	private Socket chatSocket;
	private ObjectInputStream inChat;
	private ObjectInputStream inConnect;
	private ObjectOutputStream outChat;
	private ObjectOutputStream outConnect;
	private int chat_id;
	private String username;
	private ArrayList<User> userList = new ArrayList<User>();
	private boolean group;
	private ChatMemberPanel chatMemberPanel;
	private int chatVert = 0;
	private JLabel messageTextLabel;

	// Thread tRecv = new Thread(new RecvThread());

	public ChatWindow(String username, int id, ArrayList<User> userList,
			ChatMemberPanel chatMemPanel) {
		group = false;
		chatMemberPanel = chatMemPanel;
		filler = new ContactTabListFiller();
		chat_id = id;
		this.username = username;
		this.userList = userList;
		initComponents();

	}

	public ChatWindow(String username, int id, ArrayList<User> userList,
			ChatMemberPanel chatMemPanel, boolean groupChat) {
		group = groupChat;
		chatMemberPanel = chatMemPanel;
		filler = new ContactTabListFiller();
		chat_id = id;
		this.username = username;
		this.userList = userList;
		initComponents();

	}

	public boolean isGroup() {
		return group;
	}

	public ChatMemberPanel getChatMemPanel() {
		return chatMemberPanel;
	}

	// Receive message
	// class Receive extends Thread{
	// public void run(){
	// System.out.println("in receive.run() ");
	// try{
	// while(true){
	// String date = inChat.readUTF();
	// System.out.println("in receive.run() after date");
	// String username = inChat.readUTF();
	// String message = inChat.readUTF();
	// putMessage(date, username, message);
	//
	// }
	// }catch(IOException e){
	// }
	// }
	// }

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jPanel1 = new javax.swing.JPanel();
		jPanel2 = new javax.swing.JPanel();
		jScrollPane2 = new javax.swing.JScrollPane();
		sendTextArea = new javax.swing.JTextArea();
		sendTextArea.setFont(new Font("Arial", Font.PLAIN, 12));
		sendButton = new javax.swing.JButton();
		jScrollPane1 = new javax.swing.JScrollPane();
		jPanel3 = new javax.swing.JPanel();
		messageArea = new javax.swing.JPanel();
		jPanel2.setOpaque(false);
		setOpaque(false);

		sendButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {

				sendMessage();

			}
		});

		javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(
				jPanel1);
		jPanel1.setLayout(jPanel1Layout);
		jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 100,
				Short.MAX_VALUE));
		jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 100,
				Short.MAX_VALUE));

		addComponentListener(new java.awt.event.ComponentAdapter() {
			public void componentResized(java.awt.event.ComponentEvent evt) {
				formComponentResized(evt);
			}
		});

		sendTextArea.setLineWrap(true);

		sendTextArea.addKeyListener(this);

		sendTextArea.setColumns(20);
		sendTextArea.setRows(4);
		sendTextArea.setBorder(javax.swing.BorderFactory
				.createLineBorder(new java.awt.Color(0, 0, 0)));
		jScrollPane2.setViewportView(sendTextArea);

		sendButton.setText("Send");

		javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(
				jPanel2);
		jPanel2.setLayout(jPanel2Layout);
		jPanel2Layout
				.setHorizontalGroup(jPanel2Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel2Layout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												jPanel2Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addGroup(
																jPanel2Layout
																		.createSequentialGroup()
																		.addGap(0,
																				0,
																				Short.MAX_VALUE)
																		.addComponent(
																				sendButton))
														.addComponent(
																jScrollPane2,
																javax.swing.GroupLayout.Alignment.TRAILING))
										.addContainerGap()));
		jPanel2Layout
				.setVerticalGroup(jPanel2Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel2Layout
										.createSequentialGroup()
										.addComponent(
												jScrollPane2,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												86,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(sendButton)
										.addContainerGap(
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		messageArea.setBackground(new java.awt.Color(255, 255, 255));
		messageArea.setBorder(javax.swing.BorderFactory
				.createLineBorder(new java.awt.Color(0, 0, 0)));

		javax.swing.GroupLayout messageAreaLayout = new javax.swing.GroupLayout(
				messageArea);
		messageArea.setLayout(messageAreaLayout);
		messageAreaLayout.setHorizontalGroup(messageAreaLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGap(0, 446, Short.MAX_VALUE));
		messageAreaLayout.setVerticalGroup(messageAreaLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGap(0, 180, Short.MAX_VALUE));

		javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(
				jPanel3);
		jPanel3.setLayout(jPanel3Layout);
		jPanel3Layout.setHorizontalGroup(jPanel3Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addComponent(
				messageArea, javax.swing.GroupLayout.DEFAULT_SIZE,
				javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
		jPanel3Layout.setVerticalGroup(jPanel3Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addComponent(
				messageArea, javax.swing.GroupLayout.DEFAULT_SIZE,
				javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));

		jScrollPane1.setViewportView(jPanel3);

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
		this.setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE,
						javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
				.addComponent(jScrollPane1,
						javax.swing.GroupLayout.DEFAULT_SIZE, 800,
						Short.MAX_VALUE));
		layout.setVerticalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addComponent(jScrollPane1,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										1, Short.MAX_VALUE)
								.addPreferredGap(
										javax.swing.LayoutStyle.ComponentPlacement.RELATED)
								.addComponent(jPanel2,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										javax.swing.GroupLayout.PREFERRED_SIZE)));
	}// </editor-fold>

	protected void sendMessage() {
		// TODO Auto-generated method stub

		if (sendTextArea.getText().trim().length() != 0) {

			String message = sendTextArea.getText();

			String date = getDate();

			sendTextArea.setText("");

			sendTextArea.requestFocus();

			String str = ("<b> " + username + " &nbsp &nbsp &nbsp &nbsp  "
					+ date + "</b> \n " + message + "");

			try {
				outChat = new ObjectOutputStream(new Socket(IP.getServerIP(),
						Port.getServerPort()).getOutputStream());
				if (!group) {
					outChat.writeObject(F.CHAT_MESSAGE);
				} else {
					outChat.writeObject(F.GROUP_MESSAGE);
				}
				outChat.writeObject(this.getId());
				outChat.writeObject(str);

				outChat.close();
			} catch (IOException ioe) {

			}

		}
	}

	public int getId() {
		return chat_id;
	}

	public ArrayList<User> getUserList() {
		return userList;
	}

	JPanel chatStamp;
	JTextArea messageTextArea;
	
	ArrayList<JLabel> messageTextLabelList = new ArrayList<JLabel>();

	public void putMessage(String message) {
		messageTextLabel = new JLabel();
		
		messageTextLabelList.add(messageTextLabel);

		Border paddingBorder = BorderFactory.createEmptyBorder(5,10,5,10);
		
		messageTextLabel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(),paddingBorder));

		// Layouts
		ColumnLayout chatStampLayout = new ColumnLayout(0, 0, 0, 0);
		messageArea.setLayout(chatStampLayout);
		
		// Trolleri
		messageArea.setBackground(Color.WHITE);

		messageTextLabel = wrapLabelText(messageTextLabel, message,
				messageArea.getWidth()- 100);
		messageTextLabel.setFont(new Font("Arial", Font.PLAIN, 12));

		messageArea.add(messageTextLabel);
		messageArea.setMinimumSize(new Dimension(0, messageArea
				.getPreferredSize().height));
		jPanel3.setPreferredSize(new Dimension(0, messageArea
				.getPreferredSize().height));

		if(isGroup())
			messageTextLabel.addMouseListener(new RightClicker(messageTextLabel));

		messageArea.scrollRectToVisible(new Rectangle(0, 10000, 1, 1));
	}

	private class RightClicker extends MouseAdapter {
		
		private JLabel label;
		
		public RightClicker(JLabel label){
			
			this.label = label;
		}
		public void mousePressed(MouseEvent e) {
			if (e.isMetaDown()) {
				doPop(e, label);
			}
		}

		private void doPop(MouseEvent e, JLabel label) {
			PopUpDemo menu = new PopUpDemo(label);
			menu.show(e.getComponent(), e.getX(), e.getY());
		}
	}

	class PopUpDemo extends JPopupMenu {
		JMenuItem anItem;

		public PopUpDemo(JLabel label) {

			anItem = new JMenuItem("Save as Sticky Note");
			anItem.addMouseListener(new SaveStickyNote(label));
			add(anItem);
		}
	}

	class SaveStickyNote extends MouseAdapter {
		
		private JLabel label;
		
		public SaveStickyNote(JLabel label){
			
			this.label = label;
		}

		public void mousePressed(MouseEvent e) {

			saveStickyNote(label.getText());
		}

		public void saveStickyNote(String message) {
			System.out.println("SAVED!");
			System.out.println(message);
			 filler.saveStickyNote(chat_id, message);
		}
	}

	public ContactTabListFiller getFiller() {
		return filler;
	}

	public String getUsername() {

		/*
		 * 
		 * GET USERNAME FROM DATABASE
		 */

		return null;
	}

	public String getDate() {

		DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Date date = new Date();
		return dateFormat.format(date);
	}

	private void formComponentResized(java.awt.event.ComponentEvent evt) {
		// TODO add your handling code here:

		// messageArea.setPreferredSize(new
		// Dimension(0,messageArea.getHeight()));

		jPanel3.scrollRectToVisible(new Rectangle(0,
				messageArea.getHeight() + 100000, 1, 1));
	}

	// Variables declaration - do not modify
	private javax.swing.JPanel jPanel1;
	private javax.swing.JPanel jPanel2;
	javax.swing.JPanel jPanel3;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JScrollPane jScrollPane2;
	javax.swing.JPanel messageArea;
	private javax.swing.JButton sendButton;
	private javax.swing.JTextArea sendTextArea;

	// End of variables declaration
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub

		int key = e.getKeyCode();
		if (key == KeyEvent.VK_ENTER) {

			if (e.isShiftDown()) {

				sendTextArea.append(" \n");

			} else {

				e.setKeyCode(0);
				sendMessage();
				System.out.println(e.getKeyCode());
			}

		}

	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
	}

	// private class RecvThread implements Runnable {
	//
	// public void run() {
	// try {
	// while (true) {
	// String date = inChat.readUTF();
	// String username = inChat.readUTF();
	// String message = inChat.readUTF();
	// putMessage(date, username, message);
	// }
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	//
	// }
	//
	// }

	private JLabel wrapLabelText(JLabel label, String text, int width) {
		FontMetrics fm = label.getFontMetrics(label.getFont());

		int containerWidth = width;
		
		BreakIterator boundary = BreakIterator.getWordInstance();
		boundary.setText(text);

		StringBuffer trial = new StringBuffer();
		StringBuffer real = new StringBuffer("<html>");

		int start = boundary.first();
		for (int end = boundary.next(); end != BreakIterator.DONE; start = end, end = boundary
				.next()) {
			String word = text.substring(start, end);
			if (!word.equals(" \n")) {
				trial.append(word);
				int trialWidth = SwingUtilities.computeStringWidth(fm,
						trial.toString());
				if (trialWidth > containerWidth) {
					trial = new StringBuffer(word);
					real.append(" <br> ");
				}
				real.append(word);
			} else{
				trial = new StringBuffer(word);
				real.append(" <br> ");
			}
		}

		real.append("</html>");

		label.setText(real.toString());

		return label;
	}

}
